﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.ServiceModel;
using landlord2lib;

namespace landlord2
{
    [CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant, UseSynchronizationContext = false)]
    public class GameClient : IClientCallback
    {
        private static GameClient g_client;
        private IClient m_client;
        private DuplexChannelFactory<IClient> m_proxy;
        private Guid m_guid;
        private string m_name;
        private int m_gender;
        private int? m_table;
        private int? m_seat;

        public GameClient()
        {
            m_guid = Guid.NewGuid();
        }

        ~GameClient()
        {
            if (m_proxy.State != CommunicationState.Closed)
            {
                try
                {
                    m_proxy.Close();
                }
                catch
                {
                    m_proxy.Abort();
                }
            }
        }
        
        public static GameClient CreateInstance(string ip, int port)
        {
            string uri = string.Format("net.tcp://{0}:{1}/landlord2", ip, port);
            g_client = new GameClient();
            InstanceContext context = new InstanceContext(g_client);
            NetTcpBinding binding = new NetTcpBinding();
            binding.Security.Mode = SecurityMode.None;
            binding.ReliableSession.Enabled = true;
            binding.ReliableSession.Ordered = true;
            binding.ReliableSession.InactivityTimeout = TimeSpan.FromSeconds(15);
            g_client.m_proxy = new DuplexChannelFactory<IClient>(context, binding);
            g_client.m_client = g_client.m_proxy.CreateChannel(new EndpointAddress(uri));
            return g_client;
        }

        public IClient Client
        {
            get
            {
                return m_client;
            }
        }

        public static GameClient Current
        {
            get
            {
                return g_client;
            }
        }

        public Guid Guid
        {
            get
            {
                return m_guid;
            }
        }

        public string Name
        {
            get
            {
                return m_name;
            }
            set
            {
                m_name = value;
            }
        }

        public int Gender
        {
            get
            {
                return m_gender;
            }
            set
            {
                m_gender = value;
            }
        }

        public int? Table
        {
            get
            {
                return m_table;
            }
            set
            {
                m_table = value;
            }
        }

        public int? Seat
        {
            get
            {
                return m_seat;
            }
            set
            {
                m_seat = value;
            }
        }

        public int SeatToPos(int seat)
        {
            return (seat + 4 - m_seat.Value) % 4;
        }

        public int PosToSeat(int pos)
        {
            return (pos + m_seat.Value) % 4;
        }

        public delegate void OnTableListDelegate(DataSet ds);
        public OnTableListDelegate OnTableList;
        public void TableList(DataSet ds)
        {
            if (OnTableList != null) OnTableList(ds);
        }

        public delegate void OnOpenMainWindowDelegate();
        public OnOpenMainWindowDelegate OnOpenMainWindow;
        public void OpenMainWindow()
        {
            if (OnOpenMainWindow != null) OnOpenMainWindow();
        }

        public delegate void OnPlayerInfoDelegate(DataSet ds);
        public OnPlayerInfoDelegate OnPlayerInfo;
        public void PlayerInfo(DataSet ds)
        {
            if (OnPlayerInfo != null) OnPlayerInfo(ds);
        }

        public delegate void OnPlayerReadyDelegate(int seat);
        public OnPlayerReadyDelegate OnPlayerReady;
        public void PlayerReady(int seat)
        {
            if (OnPlayerReady != null) OnPlayerReady(seat);
        }

        public delegate void OnGenerateCardDelegate(Card[] cards);
        public OnGenerateCardDelegate OnGenerateCard;
        public void GenerateCard(Card[] cards)
        {
            if (OnGenerateCard != null) OnGenerateCard(cards);
        }

        public delegate void OnCallLordDelegate(int seat, int call);
        public OnCallLordDelegate OnCallLord;
        public void CallLord(int seat, int call)
        {
            if (OnCallLord != null) OnCallLord(seat, call);
        }

        public delegate void OnCallLordResultDelegate(int seat, int call);
        public OnCallLordResultDelegate OnCallLordResult;
        public void CallLordResult(int seat, int call)
        {
            if (OnCallLordResult != null) OnCallLordResult(seat, call);
        }

        public delegate void OnGiveLordCardDelegate(Card[] cards, int point);
        public OnGiveLordCardDelegate OnGiveLordCard;

        public void GiveLordCard(Card[] cards, int point)
        {
            if (OnGiveLordCard != null) OnGiveLordCard(cards, point);
        }

        public delegate void OnShowLordCardDelegate(int seat, Card[] cards, int point);
        public OnShowLordCardDelegate OnShowLordCard;
        public void ShowLordCard(int seat, Card[] cards, int point)
        {
            if (OnShowLordCard != null) OnShowLordCard(seat, cards, point);
        }

        public delegate void OnSendCardDelegate(int seat);
        public OnSendCardDelegate OnSendCard;

        public void SendCard(int seat)
        {
            if (OnSendCard != null) OnSendCard(seat);
        }

        public delegate void OnSendCardResultDelegate(int seat, Card[] cards, bool bigger);
        public OnSendCardResultDelegate OnSendCardResult;
        public void SendCardResult(int seat, Card[] cards, bool bigger)
        {
            if (OnSendCardResult != null) OnSendCardResult(seat, cards, bigger);
        }

        public delegate void OnGameResultDelegate(DataSet ds, bool win);
        public OnGameResultDelegate OnGameResult;
        public void GameResult(DataSet ds, bool win)
        {
            if (OnGameResult != null) OnGameResult(ds, win);
        }

        public delegate void OnRestartGameDelegate();
        public OnRestartGameDelegate OnRestartGame;
        public void RestartGame()
        {
            if (OnRestartGame != null) OnRestartGame();
        }

        public delegate void OnOtherDisconnectDelegate();
        public OnOtherDisconnectDelegate OnOtherDisconnect;
        public void OtherDisconnect()
        {
            if (OnOtherDisconnect != null) OnOtherDisconnect();
        }

        public delegate void OnSendChatDelegate(int seat, int gender, int index);
        public OnSendChatDelegate OnSendChat;
        public void SendChat(int seat, int gender, int index)
        {
            if (OnSendChat != null) OnSendChat(seat, gender, index);
        }

        public delegate void OnSendChatTextDelegate(int? seat, string text);
        public OnSendChatTextDelegate OnSendChatText;
        public void SendChatText(int? seat, string text)
        {
            if (OnSendChatText != null) OnSendChatText(seat, text);
        }

        public delegate void OnRobotPlayDelegate(int seat, bool ena);
        public OnRobotPlayDelegate OnRobotPlay;
        public void RobotPlay(int seat, bool ena)
        {
            if (OnRobotPlay != null) OnRobotPlay(seat, ena);
        }
    }
}
